package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumInfoService albumInfoService;

    @Autowired
    private AlbumAttributeValueService albumAttributeValueService;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private AlbumInfoServiceImpl albumInfoServiceImpl;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        Long userId = AuthContextHolder.getUserId();
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setUserId(userId);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS); // 专辑状态：0301-审核通过 后续要对接可以做修改
        // 如果是付费的，则免费试看五集 0101代表免费 0102代表vip免费 0103代表付费
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            albumInfo.setTracksForFree(5);
        }
        int insert = albumInfoMapper.insert(albumInfo);
        log.info("保存专辑信息：{}", insert > 0 ? "成功" : "失败");
        // 再向album_attribute_value表中插入数据
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            log.error("专辑标签不能为空");
            throw new GuiguException(201, "专辑标签不能为空");
        }
        List<AlbumAttributeValue> attributeValues = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
            albumAttributeValue.setAlbumId(albumInfo.getId());
            return albumAttributeValue;
        }).toList();

        if (!CollectionUtils.isEmpty(attributeValues)) {
            boolean saved = albumAttributeValueService.saveBatch(attributeValues);
            log.info("保存专辑标签：{}", saved ? "成功" : "失败");
        }

        // 保存专辑的统计
        // todo 此处必须使用代理对象
        albumInfoServiceImpl.saveAlbumStat(albumInfo.getId());// 自我注入代理对象
        // 将专辑信息保存到ES 使用MQ
        log.info("将专辑信息保存到ES");
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumInfo.getId().toString());
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> page, AlbumInfoQuery albumInfoQuery) {
        // 需要联合album_stat表查询统计量等信息
        return albumInfoMapper.findUserAlbumPage(page, albumInfoQuery);
    }

    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (albumInfo == null) {
            throw new GuiguException(201, "专辑不存在");
        }
        List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
        return albumInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        // 先删除缓存
//        redisTemplate.delete(RedisConstant.CACHE_INFO_PREFIX + albumId);

        Long userId = AuthContextHolder.getUserId();
        // 更新album_info表 和 album_attribute_value表
        // 查询老数据
        AlbumInfo albumInfoOld = albumInfoMapper.selectById(albumId);
        if (albumInfoOld == null) {
            throw new GuiguException(201, "专辑不存在");
        }
        AlbumInfo albumInfoNew = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfoNew);
        albumInfoNew.setId(albumId);
        albumInfoNew.setUserId(userId);

        // 判断一下是从免费转付费 或者 付费转免费
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoOld.getPayType()) && SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            // 付费转免费
            albumInfoNew.setTracksForFree(0);
            albumInfoNew.setVipDiscount(new BigDecimal(-1));
            albumInfoNew.setDiscount(new BigDecimal(-1));
        } else if (SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoOld.getPayType()) && !SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            // 免费转付费
            albumInfoNew.setTracksForFree(5);
        }
        albumInfoMapper.updateById(albumInfoNew);

        // 删除album_attribute_value表中的旧数据
        int delete = albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        log.info("删除专辑标签：{}", delete > 0 ? "成功" : "失败");
        // 再向album_attribute_value表中插入数据
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            log.error("专辑标签不能为空");
            throw new GuiguException(201, "专辑标签不能为空");
        }
        List<AlbumAttributeValue> attributeValues = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
            albumAttributeValue.setAlbumId(albumId);
            return albumAttributeValue;
        }).toList();
        if (!CollectionUtils.isEmpty(attributeValues)) {
            boolean saved = albumAttributeValueService.saveBatch(attributeValues);
            log.info("保存专辑标签：{}", saved ? "成功" : "失败");
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeAlbumInfo(Long albumId) {
        // 删除album_info表 和 album_attribute_value表 和 album_stat表
        // 删除专辑之前 看看该专辑下是否有歌曲 有则不允许删除
        Long count = trackInfoMapper.selectCount(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId));
        if (count > 0) {
            throw new GuiguException(201, "专辑下有歌曲，请勿删除");
        }
        int i = albumInfoMapper.deleteById(albumId);
        log.info("删除专辑：{}", i > 0 ? "成功" : "失败");

        int delete = albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        log.info("删除专辑下标签：{}", delete > 0 ? "成功" : "失败");

        int delete1 = albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        log.info("删除专辑统计：{}", delete1 > 0 ? "成功" : "失败");

        // 删除ES中的专辑
        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId.toString());

    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        return albumInfoMapper.selectList(new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId));
    }

    @Override
    public AlbumStatVo getAlbumStat(Long albumId) {
        // 查询album_stat表
        return albumStatMapper.getAlbumStat(albumId);
    }

    @Override
    public List<Long> findAllAlbumId() {
        return albumInfoMapper.selectList(new LambdaQueryWrapper<AlbumInfo>().select(AlbumInfo::getId).eq(AlbumInfo::getIsDeleted, 0)).stream().map(AlbumInfo::getId).toList();
    }

    @Override
    public AlbumInfo getAlbumInfoByTrackId(Long trackId) {
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        if (trackInfo == null) {
            throw new GuiguException(201, "声音不存在");
        }
        Long albumId = trackInfo.getAlbumId();
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        if (albumInfo == null) {
            throw new GuiguException(201, "该声音对应的专辑不存在");
        }
        return albumInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumStat(Long albumId) {
        List<String> albumStatPlay = List.of(SystemConstant.ALBUM_STAT_PLAY, SystemConstant.ALBUM_STAT_SUBSCRIBE, SystemConstant.ALBUM_STAT_BROWSE, SystemConstant.ALBUM_STAT_COMMENT);
        albumStatPlay.stream().forEach(statType -> {
            AlbumStat albumStat = new AlbumStat();
            albumStat.setAlbumId(albumId);
            albumStat.setStatType(statType);
            albumStatMapper.insert(albumStat);
        });
    }

}
